package com.ruoyi.alarmmanagement.job;

import cn.hutool.core.util.NumberUtil;
import com.ruoyi.alarmmanagement.domain.DmWarn;
import com.ruoyi.alarmmanagement.entity.TerminalWarn;
import com.ruoyi.alarmmanagement.entity.WarnStrategy;
import com.ruoyi.alarmmanagement.mapper.DmWarnMapper;
import com.ruoyi.alarmmanagement.mapper.WarnStrategyMapper;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 预警信息生成抽象类
 *
 * @author TsingYu
 * @version 1.0
 * @date 2024/8/12 10:45
 */
@Slf4j
public abstract class BaseWarnJob {
    /**
     * 子类注册表
     */
    private static final Set<Class<? extends BaseWarnJob>> REGISTRY = new HashSet<>(20);

    /**
     * 子类在构造时会自动注册自己
     */
    public BaseWarnJob() {
        register(this.getClass());
    }

    private static void register(Class<? extends BaseWarnJob> clazz) {
        REGISTRY.add(clazz);
    }

    public static Set<Class<? extends BaseWarnJob>> getSubClasses() {
        return REGISTRY;
    }

    @Resource(name = "sqlSessionFactory")
    private SqlSessionFactory sqlSessionFactory;

    protected DmWarn convertTerminalWarnToDmWarn(TerminalWarn terminalWarn) {
        return DmWarn.builder().warnParamType(Convert.toInt(terminalWarn.getWarnType()))
                .createTime(new Date())
                .freezeTime(DateUtils.dateTime(terminalWarn.getFreezeDate()))
                .recentlyWarnTime(terminalWarn.getReadTime())
                .startTime(terminalWarn.getReadTime())
                .description(DictUtils.getDictLabel("warn_param_type", terminalWarn.getWarnType()))
                .targetId(terminalWarn.getLocationNb())
                .tenantId(terminalWarn.getTenantId())
                .referenceValue(terminalWarn.getRefValue())
                .warnValue(terminalWarn.getWarnValue())
                .value(NumberUtil.sub(terminalWarn.getWarnValue(), terminalWarn.getRefValue()))
                .handleStatus(0)
                .warnStatus(0)
                .pd("0")
                .targetType(Convert.toInt(terminalWarn.getTerminalType()))
                .terminalType(WarnStrategy.WARN_TARGET_TYPE_ELE.equals(terminalWarn.getTerminalType()) ? (short) 2 : (short) 1)
                .build();
    }

    protected WarnStrategyMapper getWarnStrategyMapper(){
        return SpringUtils.getBean(WarnStrategyMapper.class);
    }

    /**
     * 批量新增预警信息
     *
     * @param warnList TerminalWarnList
     * @param warnType 对应{@link DmWarn#getWarnType()}
     * @return 是否成功
     */
    protected boolean insertWarnBatch(List<TerminalWarn> warnList, Integer warnType) {
        try (SqlSession session = sqlSessionFactory.openSession()) {
            DmWarnMapper mapper = session.getMapper(DmWarnMapper.class);
            for (TerminalWarn terminalWarn : warnList) {
                DmWarn warn = convertTerminalWarnToDmWarn(terminalWarn);
                warn.setWarnType(warnType);
                mapper.insert(warn);

            }
            return true;
        } catch (Exception e) {
            log.error("预警数据生成失败", e);
            return false;
        }
    }

    /**
     * 获取预警参数类型
     *
     * @return 预警参数类型
     */
    protected abstract String getWarnParamType();

    /**
     * 获取预警类型
     *
     * @return 预警类型
     */
    protected abstract int getWarnType();


    /**
     * 执行预警数据生成
     *
     * @param date 生成指定日期的预警数据
     */
    public abstract void execute(Date date);
}
